/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui.dataimportwiz;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.util.Map;
import java.util.TreeMap;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import who.tmap.bo.Attrs;
import who.tmap.common.TMapException;
import who.tmap.imp.CSVImportAdapter;
import who.tmap.imp.ImportAdapter;
import who.tmap.imp.impl.ImportAdapterFactory;
import who.tmap.ui.util.FileChooserFilter;
import who.tmap.ui.util.MiscUIHelper;
import who.tmap.ui.util.jsorttable.JSortTable;
import who.tmap.ui.util.jsorttable.SortTableModel;

/**
 * @author stl
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class JFrameCSVImportWizard extends JInternalFrame implements DataImportWizardFrame {
   
    protected Attrs table;

    private static final String SEMI_COLON ="Semicolon";    
    private static final String COMMA ="Comma";
    private static final String TAB ="Tab";
    private static final String OTHER_FIELD_DELIMITER ="Other";
    
    private static final FieldDelimiter[] delimiters =new FieldDelimiter[ 4 ];
    
    private static final int OTHER_FIELD_DELIMITER_IDX =3;
    private static final int DEFAULT_FIELD_DELIMITER_IDX =0;
    
	private javax.swing.JPanel jContentPane = null;

	private javax.swing.JLabel jLabelFieldDelimiter = null;
	private javax.swing.JLabel jLabelOtherFieldDelimiter = null;	
	private javax.swing.JPanel jPanel = null;
	private JTextField jTextFieldOtherFieldDelimiter = null;
	private JComboBox jComboBoxFieldDelimiter = null;

	private JCheckBox jCheckBoxFirstRowCFN = null;
	private JLabel jLabelDummy = null;
	private JLabel jLabelTextQualifier = null;
	private JTextField jTextFieldTextQualifier = null;
	private JLabel jLabelFileName = null;
	private JTextField jTextFieldFileName = null;
	
	private JLabel jLabelSampleData = null;
	private JButton jButtonRefreshSampleData = null;

	private JButton jButtonFileName = null;
	private JPanel jPanelTable = null;
	private JTable jTable1 = null;
	private JScrollPane jScrollPane = null;
	private JPanel jPanelMisc = null;
	
	private DataWizardTableDataModel dataModel =null;
	
	private JInternalFrame thisFrame =this;
	
	
	/**
	 * This is the default constructor
	 */
	public JFrameCSVImportWizard() {
		super();
		initialize();
	}
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(534, 283);
		this.setContentPane(getJContentPane());
	}
	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private javax.swing.JPanel getJContentPane() {
		if (jContentPane == null) {
			
			jContentPane = new javax.swing.JPanel();
			jContentPane.setLayout(new BorderLayout());

			jContentPane.add(getJPanel(), java.awt.BorderLayout.CENTER);
		}
		return jContentPane;
	}
	/**
	 * This method initializes jLabelFieldDelimiter
	 * 
	 * @return javax.swing.JLabel
	 */
	private javax.swing.JLabel getJLabelFieldDelimiter() {
		if(jLabelFieldDelimiter == null) {
			jLabelFieldDelimiter = new javax.swing.JLabel();
			jLabelFieldDelimiter.setText("Field delimiter");
		}
		return jLabelFieldDelimiter;
	}
	
	/**
	 * This method initializes jLabelFieldDelimiter
	 * 
	 * @return javax.swing.JLabel
	 */
	private javax.swing.JLabel getJLabelOtherFieldDelimiter() {
		if(jLabelOtherFieldDelimiter == null) {
		    jLabelOtherFieldDelimiter = new javax.swing.JLabel();
		    jLabelOtherFieldDelimiter.setText("Other Field delimiter");
		}
		return jLabelOtherFieldDelimiter;
	}	
	
	/**
	 * This method initializes jLabelFileName
	 * 
	 * @return javax.swing.JLabel
	 */
	private javax.swing.JLabel getJLabelFileName() {
		if(jLabelFileName == null) {
			jLabelFileName = new javax.swing.JLabel();
			jLabelFileName.setText("File name");
		}
		return jLabelFileName;
	}	
	
	/**
	 * This method initializes jLabelTextQualifier
	 * 
	 * @return javax.swing.JLabel
	 */
	private javax.swing.JLabel getJLabelTextQualifier() {
		if(jLabelTextQualifier == null) {
			jLabelTextQualifier = new javax.swing.JLabel();
			jLabelTextQualifier.setText("Text qualifier");
		}
		return jLabelTextQualifier;
	}	
	
	/**
	 * This method initializes jLabelSampleData
	 * 
	 * @return javax.swing.JLabel
	 */
	private javax.swing.JLabel getJLabelSampleData() {
		if(jLabelSampleData == null) {
			jLabelSampleData = new javax.swing.JLabel();
			jLabelSampleData.setText("Sample data");
		}
		return jLabelSampleData;
	}	
	
	/**
	 * This method initializes jLabelDummy
	 * 
	 * @return javax.swing.JLabel
	 */ 
	private javax.swing.JLabel getJLabelDummy() {
		if(jLabelDummy == null) {
			jLabelDummy = new javax.swing.JLabel();
			jLabelDummy.setText(" ");
		}
		return jLabelDummy; 
	}		
	
	private javax.swing.JLabel getNewJLabelDummy() {
		javax.swing.JLabel jNewLabelDummy = new javax.swing.JLabel();
		jNewLabelDummy.setText(" ");

		return jNewLabelDummy;
	}		
	
	
	/**
	 * This method initializes jPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel() {
		if(jPanel == null) {
			jPanel = new javax.swing.JPanel();
			
			jPanel.setLayout(new BorderLayout());
			
			jPanel.add(getJPanelMisc(), BorderLayout.NORTH);
			jPanel.add(getJPanelTable(), BorderLayout.CENTER);
				
		}
		return jPanel;
	}
	/**
	 * This method initializes jTextFieldOtherFieldDelimiter	
	 * 	
	 * @return javax.swing.JTextField	
	 */    
	private JTextField getJTextFieldOtherFieldDelimiter() {
		if (jTextFieldOtherFieldDelimiter == null) {
			jTextFieldOtherFieldDelimiter = new JTextField();
			jTextFieldOtherFieldDelimiter.setText("");
		}
		return jTextFieldOtherFieldDelimiter;
	}

	/**
	 * This method initializes jCheckBoxFirstRowCFN	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */    
	private JCheckBox getJCheckBoxFirstRowCFN() {
		if (jCheckBoxFirstRowCFN == null) {
			jCheckBoxFirstRowCFN = new JCheckBox();
			jCheckBoxFirstRowCFN.setText("Field names in 1st row");
		}
		return jCheckBoxFirstRowCFN;
	}
	/**
	 * This method initializes jTextFieldTextQualifier	
	 * 	
	 * @return javax.swing.JTextField	
	 */    
	private JTextField getJTextFieldTextQualifier() {
		if (jTextFieldTextQualifier == null) {
			jTextFieldTextQualifier = new JTextField();
		}
		return jTextFieldTextQualifier;
	}
	
	/**
	 * This method initializes jTextFieldTextQualifier	
	 * 	
	 * @return javax.swing.JTextField	
	 */    
	public JTextField getJTextFieldFileName() {
		if (jTextFieldFileName == null) {
			jTextFieldFileName = new JTextField();
			jTextFieldFileName.setText("");
		}
		return jTextFieldFileName;
	}	
	/**
	 * This method initializes jButtonRefreshSampleData	
	 * 	
	 * @return javax.swing.JButton	
	 */    
	private JButton getJButtonRefreshSampleData() {
		if (jButtonRefreshSampleData == null) {
			jButtonRefreshSampleData = new JButton();
			jButtonRefreshSampleData.setText("Apply");
			jButtonRefreshSampleData.addActionListener(new java.awt.event.ActionListener() { 
				public void actionPerformed(java.awt.event.ActionEvent e) {    
				    try {
                        populateSampleData();
                    } catch (TMapException e1) {
                        new MiscUIHelper().displayErrorMessage( thisFrame, e1 );
                    }
			    }
			});
		}
		return jButtonRefreshSampleData;
	}
	
	private String getFieldSeparator() {
	    String sep =null;
	    
	    if ( ( getJComboBoxFieldDelimiter().getSelectedIndex() != -1 ) 
	            && ( !OTHER_FIELD_DELIMITER.equals( getJComboBoxFieldDelimiter().getSelectedItem().toString() ) )  ) {
	        FieldDelimiter delim =(FieldDelimiter)getJComboBoxFieldDelimiter().getSelectedItem();
	        sep =delim.getSeparator();
	    } else {
	        sep =getJTextFieldOtherFieldDelimiter().getText();
	    }
	    
	    return sep;
	}
	
	private void setFieldSeparator( String fieldSep ) {
			
		for( FieldDelimiter delimiter : delimiters ) {
			if ( delimiter.getName().equals( fieldSep ) ) {
				if ( OTHER_FIELD_DELIMITER.equals( fieldSep ) ) {
					getJComboBoxFieldDelimiter().setSelectedIndex( OTHER_FIELD_DELIMITER_IDX );
					getJTextFieldOtherFieldDelimiter().setText( fieldSep );
				} else {
					getJComboBoxFieldDelimiter().setSelectedItem( delimiter );
					getJTextFieldOtherFieldDelimiter().setText( "" );
				}
				
				break;
			}
		}
		
	}
	
	private ImportAdapter connectToAdapter() throws TMapException {
        ImportAdapter adapter =(CSVImportAdapter)ImportAdapterFactory.getInstance().getImportAdapter( ImportAdapterFactory.CSV  );
        Map<String, String> config =new TreeMap<String, String>();
        config.put( CSVImportAdapter.FILE_NAME, getJTextFieldFileName().getText() );
        config.put( CSVImportAdapter.SEPARATOR, getFieldSeparator() );
        config.put( CSVImportAdapter.TEXT_QUALIFIER, getJTextFieldTextQualifier().getText() );
        config.put( CSVImportAdapter.FIRST_ROW_CONTAINS_FIELD_NAMES, Boolean.toString( jCheckBoxFirstRowCFN.isSelected() ) );
        
        adapter.configure( config );	
        
        adapter.connect();
        
        return adapter;
	}
	
	public void populateDsProperties( Map<String, String> dsProperties ) throws Exception {
		getJTextFieldFileName().setText( dsProperties.get( CSVImportAdapter.FILE_NAME ) );
		setFieldSeparator( dsProperties.get( CSVImportAdapter.SEPARATOR ) );
		getJTextFieldTextQualifier().setText( dsProperties.get( CSVImportAdapter.TEXT_QUALIFIER ) );
		jCheckBoxFirstRowCFN.setSelected( Boolean.parseBoolean( dsProperties.get( CSVImportAdapter.FIRST_ROW_CONTAINS_FIELD_NAMES ) ) );
		
		populateSampleData();
	}
	
	public Attrs getValuesTable() throws TMapException {
	    Attrs table =null;
	    ImportAdapter adapter =connectToAdapter();
        
        try {
            table =adapter.readValues();
           
        } catch( Exception e ) {
            throw new TMapException( e );
        } finally {
            if ( adapter != null ) {
                adapter.disconnect();
            }
        }
        
        return table;
	}
	
	public void populateSampleData() throws TMapException {
	    ImportAdapter adapter =connectToAdapter();
        
        try {
            table =adapter.readSampleData();
            dataModel.setAttrs( table );
            dataModel.fireTableStructureChanged();
            
        } catch( Exception e ) {
            throw new TMapException( e );
        } finally {
            if ( adapter != null ) {
                adapter.disconnect();
            }
        }
	}
	
	public Attrs getTable() {
	    return table;
	}

	/**
	 * This method initializes jButtonFileName	
	 * 	
	 * @return javax.swing.JButton	
	 */    
	public JButton getJButtonFileName() {
		if (jButtonFileName == null) {
			jButtonFileName = new JButton();
			jButtonFileName.setText("Select...");
			jButtonFileName.addActionListener(new java.awt.event.ActionListener() { 
				public void actionPerformed(java.awt.event.ActionEvent e) {    
					JFileChooser fileChooser = new JFileChooser();
					fileChooser.addChoosableFileFilter( new FileChooserFilter( FileChooserFilter.CSV_EXT ) );
					fileChooser.setCurrentDirectory( FileChooserFilter.DATA_DIR );
			
					// Open file dialog.
					int retVal =fileChooser.showOpenDialog(	getContentPane() );
					
					if ( retVal == JFileChooser.APPROVE_OPTION ) {
					    jTextFieldFileName.setText( fileChooser.getSelectedFile().toString() );
					}
				}
			});
		}
		return jButtonFileName;
	}
	
	/**
	 * This method initializes jPanelTable	
	 * 	
	 * @return javax.swing.JPanel	
	 */    
	private JPanel getJPanelTable() {
		if (jPanelTable == null) {
			GridLayout gridLayout4 = new GridLayout();
			jPanelTable = new JPanel();
			jPanelTable.setLayout(gridLayout4);
			jPanelTable.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
	
			gridLayout4.setRows(1);
			jPanelTable.add(getJScrollPane(), null);
		}
		return jPanelTable;
	}
	
	/**
	 * This method initializes jTable1	
	 * 	
	 * @return javax.swing.JTable	
	 */    
	private JTable getJTable1() {
		if (jTable1 == null) {
			jTable1 = new JTable();
			
			dataModel = new DataWizardTableDataModel();
			jTable1 =new JSortTable( (SortTableModel)dataModel );			
		} 
		return jTable1;
	}
	
	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */    
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getJTable1());
		}
		return jScrollPane;
	}
	
	/**
	 * This method initializes jPanelMisc	
	 * 	
	 * @return javax.swing.JPanel	
	 */    
	private JPanel getJPanelMisc() {
		if (jPanelMisc == null) {
			GridLayout gridLayout2 = new GridLayout(6,3);
			jPanelMisc = new JPanel();
			jPanelMisc.setLayout(gridLayout2);
			jPanelMisc.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,5,5));
			
			jPanelMisc.add(getJLabelFileName(), null);
			jPanelMisc.add(getJTextFieldFileName(), null);
			jPanelMisc.add(getJButtonFileName(), null);			
			
			jPanelMisc.add(getJLabelFieldDelimiter(), null);
			jPanelMisc.add( getJComboBoxFieldDelimiter(), null );		
			jPanelMisc.add( getNewJLabelDummy(), null );
			
			jPanelMisc.add(getJLabelOtherFieldDelimiter(), null);
			jPanelMisc.add(getJTextFieldOtherFieldDelimiter(), null);
			jPanelMisc.add( getNewJLabelDummy(), null );			
			
			jPanelMisc.add(getJCheckBoxFirstRowCFN(), null);
			jPanelMisc.add( getNewJLabelDummy(), null);
			jPanelMisc.add( getNewJLabelDummy(), null );
			
			jPanelMisc.add(getJLabelTextQualifier(), null);
			jPanelMisc.add(getJTextFieldTextQualifier(), null);
			jPanelMisc.add( getNewJLabelDummy(), null );
			
			jPanelMisc.add(getJLabelSampleData(), null);
			jPanelMisc.add( getNewJLabelDummy(), null );			
			jPanelMisc.add(getJButtonRefreshSampleData(), null);
		}
		return jPanelMisc;
	}
	
	private JComboBox getJComboBoxFieldDelimiter() {
		if (jComboBoxFieldDelimiter == null) {
			
			delimiters[ 0 ] =new FieldDelimiter( SEMI_COLON, ";" );			
			delimiters[ 1 ] =new FieldDelimiter( COMMA, "," );
			delimiters[ 2 ] =new FieldDelimiter( TAB, "\t" );
			delimiters[ 3 ] =new FieldDelimiter( OTHER_FIELD_DELIMITER, "other" );
			
		    jComboBoxFieldDelimiter = new JComboBox();
		    for( FieldDelimiter delimiter : delimiters ) {
		    	jComboBoxFieldDelimiter.addItem( delimiter );
		    }
		    
		    jComboBoxFieldDelimiter.setSelectedIndex( DEFAULT_FIELD_DELIMITER_IDX );
		}
		return jComboBoxFieldDelimiter;
	}	
	
	private class FieldDelimiter {
	    private String name;
	    private String separator;
	    
	    public FieldDelimiter( String name, String separator ) {
	        this.name =name;
	        this.separator =separator;
	    }
	    
	    public String getName() {
	    	return name;
	    }
	    
	    public String getSeparator() {
	        return separator;
	    }
	    
	    public String toString() {
	        return name;
	    }
	}

 }  //  @jve:decl-index=0:visual-constraint="10,36"
